﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using Eqwww.Data;
using Eqwww.Domain.Models.SystemManage;
using Eqwww.App.SystemManage;
using Eqwww.Web.Areas.SystemManage.Models.Organize;
using Eqwww.Code;
using Eqwww.App.Authorize;
using Eqwww.App.Identity;
using AspNetCore;
using AutoMapper;

namespace Eqwww.Web.Areas.SystemManage.Controllers
{
    [Area("SystemManage")]
    public class OrganizeController : ControllerBase
    {
        private AuthorizeApp _authorizeApp;
        private OrganizeApp _organizeApp;
        private ApplicationDbContext _context;
        private UserApp _userApp;
        private IMapper _mapper;
        public OrganizeController(AuthorizeApp authorizeApp, 
            OrganizeApp organizeApp, 
            UserApp userApp,
            IMapper mapper, 
            ApplicationDbContext context)
        {
            _organizeApp = organizeApp;
            _authorizeApp = authorizeApp;
            _mapper = mapper;
            _userApp = userApp;
            _context = context;
        }

        [AuthFilter]
        public IActionResult Index()
        {
            var currentModuleCode = "SystemManage_Organize";
            ViewData["SelectedButtons"] = _authorizeApp.GetAuthorizedModuleButtons(User, currentModuleCode, ModuleButtonPosition.Selected);
            ViewData["InitialButtons"] = _authorizeApp.GetAuthorizedModuleButtons(User, currentModuleCode, ModuleButtonPosition.Initial);

            var data = _organizeApp.GetTreeGridList();
            return View(data);
        }

        [AuthFilter]
        public IActionResult Details(string id)
        {
            if (id == null)
                return NotFound();
            var model = _organizeApp.GetInclude(id);
            if (model == null)
                return NotFound();
            ViewData["AncestorNames"]=_organizeApp.GetAncestorNamesString(id);

            return View(model);
        }

        [AuthFilter]
        public IActionResult Create()
        {
           
            return View();
        }

        
        [HttpPost]
        [ExceptionFilter]
        [ValidateAntiForgeryToken]
        public IActionResult Create([Bind("Code,Name,ParentId,Description,OrganizeType,SortCode,OrganizeBelongType")] CreateViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                var model = _mapper.Map<OrganizeModel>(viewModel);
                return Json(_organizeApp.Create(model));
            }
            return Json(Common.ModelStateErrorResult(ModelState));
        }

        [AuthFilter]
        public IActionResult Edit(string id)
        {
            if (id == null)
            {
                return NotFoundObject();
            }

            var organize = _organizeApp.Get(id);
            if (organize == null)
            {
                return NotFoundObject();
            }
            
            var viewModel = _mapper.Map<EditViewModel>(organize);
            return View(viewModel);
        }

        
        [HttpPost]
        [ExceptionFilter]
        [ValidateAntiForgeryToken]
        public IActionResult Edit(string id, [Bind("Id,Code,Name,ParentId,Description,OrganizeType,SortCode,OrganizeBelongType")] EditViewModel viewModel)
        {
            if (id != viewModel.Id)
            {
                return Error("id与Model Id不一致");
            }

            if (ModelState.IsValid)
            {
                var model = _organizeApp.Get(id);
                _mapper.Map(viewModel, model);
                return Json(_organizeApp.Update(model));
                
            }
            return Json(Common.ModelStateErrorResult(ModelState));
        }

        

        
        [HttpPost, ActionName("Delete")]
        [ExceptionFilter]
        [ValidateAntiForgeryToken]
        public IActionResult DeleteConfirmed(string id)
        {
            return Json(_organizeApp.Remove(id));
        }

        public IActionResult TreeCollapse(bool? HideTopNode)
        {
            ViewData["HideTopNode"] = HideTopNode;
            ViewData["Items"] = _organizeApp.GetTreeCollapseItems();
            return View();
        }



        public IActionResult OrganizeTree()
        {
            var isGuanLiYuan = false;
            var currentUser = _userApp.GetUserAsync(User).Result;
            if (_userApp.IsInRoleAsync(currentUser, "Founder").Result)
            {
                isGuanLiYuan = true;
            }
            var isErJiDanWeiGuanLiYuan = false;
            if (_userApp.IsInRoleAsync(currentUser, "jsdwgly").Result && !isGuanLiYuan)
            {
                isErJiDanWeiGuanLiYuan = true;
            }

            ViewData["IsGuanLiYuan"] = isGuanLiYuan;
            ViewData["IsErJiDanWeiGuanLiYuan"] = isErJiDanWeiGuanLiYuan;

            var Organizes = _context.Sys_Organizes.AsNoTracking().Where(x => x.DeleteMark != true).OrderBy(x=>x.SortCode);
            var Posts = _context.Sys_Posts.AsNoTracking().Where(x => x.DeleteMark != true);
            var Users = _userApp.Users.Where(x => x.DeleteMark != true);
            var UserPosts = _context.Sys_UserPosts.ToList();

            if (isErJiDanWeiGuanLiYuan)
            {
                var currentPostIds = from p in _context.Sys_UserPosts.Where(x => x.UserId == currentUser.Id) select p.PostId;
                var currentPosts = _context.Sys_Posts.Where(x => x.DeleteMark != true && currentPostIds.Contains(x.Id));
                var currentOrganizeIds = from p in _context.Sys_Posts.Where(x => x.DeleteMark != true && currentPostIds.Contains(x.Id)) select p.OrganizeId;
                var currentOrganizes = Organizes.Where(x => currentOrganizeIds.Distinct().Contains(x.Id));

                var OS = from p in currentOrganizes.OrderBy(x=>x.SortCode)
                         select new ZTreeNodeModel
                         {
                             id = p.Id,
                             pid = p.ParentId,
                             name = p.Name,
                             nodetype = "organize",
                             open=string.IsNullOrEmpty(p.ParentId)?true:false
                         };

                var PS = from p in Posts.Where(x => currentOrganizeIds.Contains(x.OrganizeId))
                         select new ZTreeNodeModel
                         {
                             id = p.Id,
                             pid = p.OrganizeId,
                             name = p.Name,
                             nodetype = "post"
                         };

                var userList = new List<ZTreeNodeModel>();
                foreach (var p in PS)
                {
                    var usersWithPostIds = from q in UserPosts
                                           where q.PostId == p.id
                                           select q.UserId;

                    var usersWithPost = from q in Users
                                        where usersWithPostIds.Contains(q.Id)
                                        select new ZTreeNodeModel
                                        {
                                            id = q.Id,
                                            pid = p.id,
                                            name = q.RealName,
                                            nodetype = "user"
                                        };

                    userList.AddRange(usersWithPost);
                }

                var data = OS.Union(PS).Union(userList);

                ViewData["ztree"] = Newtonsoft.Json.JsonConvert.SerializeObject(data);

                return View();
            }
            else
            {

                var OS = from p in Organizes
                         select new ZTreeNodeModel
                         {
                             id = p.Id,
                             pid = p.ParentId,
                             name = p.Name,
                             nodetype = "organize",
                             open = string.IsNullOrEmpty(p.ParentId) ? true : false
                         };

                var PS = from p in Posts
                         select new ZTreeNodeModel
                         {
                             id = p.Id,
                             pid = p.OrganizeId,
                             name = p.Name,
                             nodetype = "post"
                         };

                var userList = new List<ZTreeNodeModel>();
                foreach (var p in PS)
                {
                    var usersWithPostIds = from q in UserPosts
                                           where q.PostId == p.id
                                           select q.UserId;

                    var usersWithPost = from q in Users
                                        where usersWithPostIds.Contains(q.Id)
                                        select new ZTreeNodeModel
                                        {
                                            id = q.Id,
                                            pid = p.id,
                                            name = q.RealName,
                                            nodetype = "user"
                                        };

                    userList.AddRange(usersWithPost);
                }

                var data = OS.Union(PS).Union(userList);

                ViewData["ztree"] = Newtonsoft.Json.JsonConvert.SerializeObject(data);

                return View();
            }

           

        }

        [AuthFilter]
        public IActionResult TreeGrid()
        {
            var currentModuleCode = "SystemManage_Organize";
            ViewData["SelectedButtons"] = _authorizeApp.GetAuthorizedModuleButtons(User, currentModuleCode, ModuleButtonPosition.Selected);
            ViewData["InitialButtons"] = _authorizeApp.GetAuthorizedModuleButtons(User, currentModuleCode, ModuleButtonPosition.Initial);

            var currentPostModuleCode = "SystemManage_Organize_PostManage";
            ViewData["SelectedPostButtons"] = _authorizeApp.GetAuthorizedModuleButtonsByParentCode(User, currentPostModuleCode, ModuleButtonPosition.Selected);
            //ViewData["InitialPostButtons"] = _authorizeApp.GetAuthorizedModuleButtons(User, currentPostModuleCode, ModuleButtonPosition.Initial);

            var currentUserModuleCode = "SystemManage_Organize_UserManage";
            ViewData["SelectedUserButtons"] = _authorizeApp.GetAuthorizedModuleButtonsByParentCode(User, currentUserModuleCode, ModuleButtonPosition.Selected);
            //ViewData["InitialUserButtons"] = _authorizeApp.GetAuthorizedModuleButtons(User, currentUserModuleCode, ModuleButtonPosition.Initial);

            return View();
        }

        public IActionResult TreeGridJson()
        {
            var Organizes = _context.Sys_Organizes.AsNoTracking().Where(x => x.DeleteMark != true).OrderBy(x => x.SortCode).ToList();
            var Posts = _context.Sys_Posts.AsNoTracking().Where(x => x.DeleteMark != true).ToList();
            var UserPosts = _context.Sys_UserPosts.Include(x=>x.User).Include(x=>x.Post).AsNoTracking().Where(x=>x.Post.DeleteMark!=true&&x.User.DeleteMark!=true).ToList();

            var OrganizeNodes = from p in Organizes
                                select new
                                {
                                    Id = p.Id,
                                    Name = p.Name,
                                    Code = p.Code,
                                    SortCode = p.SortCode,
                                    CreateTime = p.CreateTime,
                                    ParentId = p.ParentId
                                };

            var PostNodes = from p in Posts
                            select new
                            {
                                p.Id,
                                p.Name,
                                p.Code,
                                p.SortCode,
                                p.CreateTime,
                                ParentId=p.OrganizeId
                            };
            var UserNodes = from p in UserPosts
                            select new
                            {
                                Id = p.User.Id,
                                Name = p.User.RealName,
                                Code = string.Empty,
                                SortCode = 0,
                                CreateTime = p.User.CreateTime,
                                ParentId = p.PostId
                            };

            var treeList = new List<TreeGridModel>();
            foreach (var item in OrganizeNodes)
            {
                var viewModel = new TreeGirdViewModel
                {
                    Id=item.Id,
                    Name=item.Name,
                    Code=item.Code,
                    CreateTime=item.CreateTime,
                    NodeType="组织"
                };
                
                TreeGridModel treeModel = new TreeGridModel();
                bool hasChildren = false;
                if (OrganizeNodes.Count(t => t.ParentId == item.Id) > 0)
                    hasChildren = true;
                if (PostNodes.Count(x => x.ParentId == item.Id) > 0)
                    hasChildren = true;
                treeModel.id = item.Id;
                treeModel.isLeaf = hasChildren;
                treeModel.parentId = item.ParentId;
                treeModel.expanded = hasChildren;
                treeModel.entityJson = viewModel.ToJson();
                treeList.Add(treeModel);
            }
            
            foreach(var item in PostNodes)
            {
                var viewModel = new TreeGirdViewModel
                {
                    Id = item.Id,
                    Name = item.Name,
                    Code = item.Code,
                    CreateTime = item.CreateTime,
                    NodeType = "岗位"
                };

                TreeGridModel treeModel = new TreeGridModel();
                bool hasChildren = false;
                if (UserNodes.Count(t => t.ParentId == item.Id) > 0)
                    hasChildren = true;
                treeModel.id = item.Id;
                treeModel.isLeaf = hasChildren;
                treeModel.parentId = item.ParentId;
                treeModel.expanded = hasChildren;
                treeModel.entityJson = viewModel.ToJson();
                treeList.Add(treeModel);

            }
            
            foreach(var item in UserNodes)
            {
                var viewModel = new TreeGirdViewModel
                {
                    Id = item.Id,
                    Name = item.Name,
                    Code = item.Code,
                    CreateTime = item.CreateTime,
                    NodeType = "人员"
                };

                TreeGridModel treeModel = new TreeGridModel();
                bool hasChildren = false;
                treeModel.id = item.Id;
                treeModel.isLeaf = hasChildren;
                treeModel.parentId = item.ParentId;
                treeModel.expanded = hasChildren;
                treeModel.entityJson = viewModel.ToJson();
                treeList.Add(treeModel);
            }
            
            return Content(treeList.TreeGridJson());

        }

    }
}
